package instances

import (
	"bytes"
	"cloud_android_backend/pkg/models/products"
	"cloud_android_backend/pkg/models/resources"
	"cloud_android_backend/pkg/utils"
	"crypto/rand"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/golang/glog"
	"github.com/jinzhu/gorm"
	"io/ioutil"
	"math/big"
	"modules.tenxcloud.com/common/composite"
	"net/http"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"
)

func init() {
	go DetectInstancesExpired()
	go func() {
		ticker := time.NewTicker(time.Minute * 1)
		for _ = range ticker.C {
			go func() {
				err := DetectInstancesExpired()
				if err != nil {
					glog.Errorf("DetectInstancesExpired failed, %s", err)
				}
			}()

		}
	}()
	//go CheckAllContainersState()
	go func() {
		ticker := time.NewTicker(time.Second * 10)
		for _ = range ticker.C {
			err := CheckAllContainersState()
			if err != nil {
				glog.Errorf("CheckAllContainersState failed, %s", err)
			}
		}
	}()
}

type InitInstancesParam struct {
	MachineId int64 `json:"machine_id"`
	ProductId int   `json:"product_id"`
}

func InitInstances(params InitInstancesParam) error {
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get database connection failed, %s", err)
		return err
	}
	machineInfo := &resources.Machines{Id: params.MachineId}
	err = machineInfo.GetById(db)
	if err != nil {
		glog.Errorf("get machine info failed, %s", err)
		return err
	}
	productInfo := &products.Products{Id: params.ProductId}
	err = productInfo.GetById(db)
	if err != nil {
		glog.Errorf("get product info failed, %s", err)
		return err
	}
	if productInfo.CpuCores > machineInfo.CpuCore {
		glog.Errorf("cpu cores is not enough")
		return fmt.Errorf("cpu cores is not enough")
	}
	if productInfo.Memory > machineInfo.Memory {
		glog.Errorf("memory is not enough")
		return fmt.Errorf("memory is not enough")
	}
	InstanceNum := ceilDivide(machineInfo.Memory, productInfo.Memory)
	containers := make([]ContainersParam, InstanceNum)
	for i := 0; i < InstanceNum; i++ {
		Name, _ := SecureRandomString(9)
		containers[i] = ContainersParam{
			Name: fmt.Sprintf("%s", Name),
		}
	}

	initContainerParams := InitContainersPara{
		InstanceNum: InstanceNum,
		DiskSize:    productInfo.Storage - 0.25,
		CpuLimit:    int64(productInfo.CpuCores),
		MemoryLimit: int64(productInfo.Memory),
		Image:       "172.20.92.60:10090/android/redroid",
		ImageTag:    "13",
		Width:       1080,
		Height:      1920,
		Harbor: Harbor{
			HarborUrl:  "172.20.92.60:10090",
			HarborUser: "admin",
			HarborPass: "Harbor@12345#tsx",
		},
		Containers: containers,
	}
	url := fmt.Sprintf("http://%s:%d/container/lifecycle/init", machineInfo.Ip, machineInfo.Port)
	// 将数据编码为 JSON
	jsonData, err := json.Marshal(initContainerParams)
	if err != nil {
		fmt.Printf("Get system info failed! json marshall err:%v", err)
		return err
	}

	// 创建 POST 请求
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Printf("Get system info failed! post err:%v", err)
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		fmt.Printf("Get system info failed! status code:%d", resp.StatusCode)
		return err
	}
	// 读取响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("Get system info failed! read body err:%v", err)
		return err
	}
	fmt.Println(string(body))
	res := struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
		Data InitContainersPara
	}{}
	err = json.Unmarshal(body, &res)
	if err != nil {
		fmt.Printf("Get system info failed! json unmarshal err:%v", err)
		return err
	}
	if res.Code != 0 {
		fmt.Printf("Get system info failed! status code:%d", res.Code)
		return fmt.Errorf(res.Msg)
	}
	if len(res.Data.Containers) != res.Data.InstanceNum {
		msg := fmt.Sprintf("init containers failed,instance num dismatch!requre:%d,get %d", len(res.Data.Containers))
		fmt.Printf(msg)
		return fmt.Errorf(msg)
	}
	fmt.Println(res.Data)
	err = saveInstance(res.Data, params)

	if err != nil {
		return err
	}
	fmt.Printf("save instance success")
	return nil
}
func saveInstance(param InitContainersPara, reqParam InitInstancesParam) error {
	db, err := composite.Database.GetOrm()
	if err != nil {
		return err
	}
	//err = db.Debug().Transaction(func(tx *gorm.DB) error {
	//
	//	fmt.Printf("init instance success")
	//	return nil
	//})
	tx := db.Begin()
	for _, container := range param.Containers {
		instance := resources.Instances{
			Name:      container.Name,
			CpuCores:  int(container.CpuLimit),
			Memory:    int(container.MemoryLimit),
			Storage:   param.DiskSize,
			Image:     container.Image,
			ImageTag:  container.ImageTag,
			AdbPort:   container.AdbPort,
			Index:     container.Index,
			Width:     container.Width,
			Height:    container.Height,
			Mac:       container.MacAddr,
			MachineId: reqParam.MachineId,
			ProductId: reqParam.ProductId,
		}
		err := instance.Create(tx)
		if err != nil {
			tx.Rollback()
			return err
		}
		fmt.Printf("save instance %s success", instance.Name)
	}
	err = tx.Commit().Error
	if err != nil {
		tx.Rollback()
		return err
	}
	return nil
}
func ceilDivide(a, b int) int {
	return (a + b - 1) / b
}
func SecureRandomString(length int) (string, error) {
	const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	ret := make([]byte, length)
	for i := 0; i < length; i++ {
		num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
		if err != nil {
			return "", err
		}
		ret[i] = letters[num.Int64()]
	}
	return string(ret), nil
}

type InitContainersPara struct {
	InstanceNum int               `json:"instance_num"`
	DiskSize    float64           `json:"disk_size"`
	CpuLimit    int64             `json:"cpu_limit"`
	MemoryLimit int64             `json:"memory_limit"`
	Image       string            `json:"image"`
	ImageTag    string            `json:"image_tag"`
	Width       int               `json:"width"`
	Height      int               `json:"height"`
	Harbor      Harbor            `json:"harbor"`
	Containers  []ContainersParam `json:"containers"`
}
type Harbor struct {
	HarborUrl  string `json:"harbor_url"`
	HarborUser string `json:"harbor_user"`
	HarborPass string `json:"harbor_pass"`
}
type ContainersParam struct {
	CpuLimit    int64  `json:"cpu_limit"`
	MemoryLimit int64  `json:"memory_limit"`
	Image       string `json:"image"`
	ImageTag    string `json:"image_tag"`
	AdbPort     int    `json:"adb_port"`
	Name        string `json:"name"`
	Index       int    `json:"index"`
	Width       int    `json:"width"`
	Height      int    `json:"height"`
	MacAddr     string `json:"mac_addr"`
}
type DestroyAllInstancesParam struct {
	MachineId int64 `json:"machine_id"`
}

func DestroyAllInstances(param DestroyAllInstancesParam) error {
	if param.MachineId <= 0 {
		return fmt.Errorf("machine id is invalid")
	}
	db, err := composite.Database.GetOrm()
	if err != nil {
		return err
	}
	machineInfo := resources.Machines{Id: param.MachineId}
	err = machineInfo.GetById(db)
	if err != nil {
		return err
	}
	url := fmt.Sprintf("http://%s:%d/container/lifecycle/destroy", machineInfo.Ip, machineInfo.Port)
	// 将数据编码为 JSON
	jsonData, err := json.Marshal(param)
	if err != nil {
		fmt.Printf("post destroy all failed! json marshall err:%v", err)
		return err
	}

	// 创建 POST 请求
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Printf("post destroy all failed! post err:%v", err)
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		fmt.Printf("post destroy all failed! status code:%d", resp.StatusCode)
		return err
	}
	// 读取响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("post destroy all failed! read body err:%v", err)
		return err
	}
	res := struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
	}{}
	err = json.Unmarshal(body, &res)
	if err != nil {
		fmt.Printf("post destroy all failed! json unmarshal err:%v", err)
		return err
	}
	if res.Code != 0 {
		fmt.Printf("post destroy all failed! status code:%d", res.Code)
		return fmt.Errorf(res.Msg)
	}
	err = db.Transaction(func(tx *gorm.DB) error {
		instance := resources.Instances{MachineId: param.MachineId}
		isntances, err := instance.GetListByMachineId(tx, param.MachineId)
		if err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return nil
			}
			return err
		}
		for _, instance := range isntances {
			err := instance.SoftDelete(tx, instance.Id)
			if err != nil {
				return err
			}
		}
		return nil
	})
	return nil
}

func InstanceConnect(instances []resources.InstanceUses) error {

	db, err := composite.Database.GetOrm()
	if err != nil {
		return err
	}
	for _, instance := range instances {
		MachineInfo := resources.Machines{Id: instance.Instances.MachineId}
		err := MachineInfo.GetById(db)
		if err != nil {
			return err
		}
		url := fmt.Sprintf("%s:%d", MachineInfo.Ip, instance.Instances.AdbPort)
		go func() {
			err := AdbConnectWithTries(url, 20, instance.Id)
			if err != nil {
				fmt.Printf("connect instance %s failed! err:%v", url, err)
			}
		}()

	}
	return nil
}

func AdbConnectWithTries(address string, tries int, instanceUsesId int64) error {
	for i := 0; i < tries; i++ {
		cmd := exec.Command("adb", "connect", address)
		var out bytes.Buffer
		var stderr bytes.Buffer
		cmd.Stdout = &out
		cmd.Stderr = &stderr
		err := cmd.Run()
		if err != nil {
			fmt.Printf("connect instance %s failed! err:%v", address, err)
		}
		if strings.Contains(out.String(), "connected") || strings.Contains(out.String(), "success") {
			go func() {
				err := ScreenshotForDevice(address, instanceUsesId)
				if err != nil {
					fmt.Printf("save instance %s screenshot failed! err:%v", address, err)
				}
			}()
			go InstallYingYongBao(address)
			fmt.Printf("connect instance %s success", address)
			return nil
		}
		time.Sleep(5 * time.Second)
	}
	return nil

}

func ScreenshotForDevice(deviceID string, instanceUsesId int64) error {
	dest := fmt.Sprintf("/var/www/html/dist/img/screenshot-%d.png", instanceUsesId)

	// 构造 adb 参数
	args := []string{}
	if deviceID != "" {
		args = append(args, "-s", deviceID)
	}
	args = append(args, "exec-out", "screencap", "-p")
	fmt.Printf("adb %s\n", strings.Join(args, " "))
	cmd := exec.Command("adb", args...)

	// 打开（或覆盖）目标文件
	outFile, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		return fmt.Errorf("无法创建/打开目标文件: %w", err)
	}
	defer outFile.Close()

	cmd.Stdout = outFile
	cmd.Stderr = os.Stderr

	if err := cmd.Run(); err != nil {
		glog.Errorf("get screenshot failed: err %v", err)
		return err
	}
	// 修复 Windows 中 CRLF 换行问题（如果有需要）
	db, err := composite.Database.GetOrm()
	instance := resources.InstanceUses{Id: instanceUsesId}
	err = instance.GetById(db)
	if err != nil {
		return err
	}
	instance.ScreenShot = strings.ReplaceAll(dest, "/var/www/html/dist", "")
	err = instance.UpdatePartFields(db, map[string]interface{}{"screen_shot": instance.ScreenShot})
	if err != nil {
		return err
	}
	return nil
}

func InstallYingYongBao(address string) error {
	cmd := exec.Command("adb", "-s", address, "install", "/root/yingyongbao.apk")
	var out bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		fmt.Printf("InstallYingYongBao %s failed! err:%v", address, err)
		return err
	}
	fmt.Println(out.String())

	return nil
}

func DetectInstancesExpired() error {
	fmt.Printf("DetectInstancesExpired start\n")
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get db failed:err %v", err)
		return err
	}
	instanceModel := resources.InstanceUses{}
	instanceUsers, err := instanceModel.GetUsingButExpiredInstances(db)
	if err != nil {
		glog.Errorf("get using but expired instances failed:err %v", err)
		return err
	}
	for _, instanceUser := range instanceUsers {
		err = db.Transaction(func(tx *gorm.DB) error {
			fmt.Printf("DetectInstancesExpired for instance id:%d\n", instanceUser.InstanceId)
			instance := resources.Instances{Id: instanceUser.InstanceId}
			err := instance.GetById(db)
			if err != nil {
				glog.Errorf("get instance failed:err %v", err)
				return err
			}
			//instance.Status = resources.InstanceStatus_NotSold
			err = instance.UpdatePartFields(tx, map[string]interface{}{"status": int(resources.InstanceStatus_NotSold)})
			if err != nil {
				glog.Errorf("get instance failed:err %v", err)
				return err
			}
			//instanceUser.Status = int(resources.InstanceUseStatusExpired)
			fmt.Printf("DetectInstancesExpired for instanceuses id:%d\n", instanceUser.Id)
			err = instanceUser.UpdatePartFields(tx, map[string]interface{}{"status": int(resources.InstanceUseStatusExpired)})
			if err != nil {
				glog.Errorf("get instance failed:err %v", err)
				return err
			}
			return nil
		})
		if err != nil {
			glog.Errorf("transaction failed:err %v", err)
			//return err
		}
	}
	fmt.Printf("DetectInstancesExpired done\n")
	return nil
}

type OpInstanceParams struct {
	InstanceUseId int64 `json:"instance_id"`
}
type OpInstanceReqParam struct {
	InstanceName string `json:"container_name"`
}

func RestartInstance(param OpInstanceParams, userId string) error {
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get database connection failed, %s", err)
		return err
	}
	instanceModel := resources.InstanceUses{Id: param.InstanceUseId}
	err = instanceModel.GetByIdWithInstanceInfo(db)
	if err != nil {
		glog.Errorf("get instance failed:err %v", err)
		return err
	}
	if instanceModel.UserId != userId {
		glog.Errorf("user %s not have permission to restart instance %d", userId, instanceModel.Id)
		return fmt.Errorf("permission denied")
	}
	instanceName := instanceModel.Instances.Name
	machineModel := resources.Machines{Id: instanceModel.Instances.MachineId}
	err = machineModel.GetById(db)
	if err != nil {
		glog.Errorf("get machine failed:err %v", err)
		return err
	}
	url := fmt.Sprintf("http://%s:%d/container/lifecycle/restart", machineModel.Ip, machineModel.Port)
	opParam := OpInstanceReqParam{
		InstanceName: instanceName,
	}
	// 将数据编码为 JSON
	jsonData, err := json.Marshal(opParam)
	if err != nil {
		fmt.Printf("Get system info failed! json marshall err:%v", err)
		return err
	}

	// 创建 POST 请求
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Printf("Get system info failed! post err:%v", err)
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		fmt.Printf("Get system info failed! status code:%d", resp.StatusCode)
		return err
	}
	// 读取响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("Get system info failed! read body err:%v", err)
		return err
	}
	var Res struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
	}
	if err := json.Unmarshal(body, &Res); err != nil {
		fmt.Printf("Get system info failed! unmarshal err:%v", err)
		return err
	}
	if Res.Code != 0 {
		fmt.Printf("Get system info failed! %s", Res.Msg)
		return err
	}
	//go func() {
	//	err := InstanceConnect([]resources.InstanceUses{instanceModel})
	//	if err != nil {
	//		fmt.Printf("connect instance %s failed! err:%v", instanceName, err)
	//	}
	//}()
	//go func() {
	//	err := CheckContainerStateWithRetries(instanceModel.Id, 30)
	//	if err != nil {
	//		fmt.Printf("check instance %s failed! err:%v", instanceName, err)
	//	}
	//}()
	//instancesModel := &instanceModel.Instances
	err = instanceModel.UpdatePartFields(db, map[string]interface{}{"state": 0, "operate_time": time.Now()})
	if err != nil {
		glog.Errorf("update instance failed:err %v", err)
		return err
	}
	return nil
}
func CheckContainerStateWithRetries(instanceUserId int64, retries int) error {
	for i := 0; i < retries; i++ {
		state, err := CheckContainerState(instanceUserId)
		if err != nil {
			return err
		}
		if state == int(resources.InstanceUseStateOnline) {
			return nil
		}
		time.Sleep(time.Second * 5)
	}
	return nil
}

func CheckContainerState(instanceUseId int64) (int, error) {
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get database connection failed, %s", err)
		return 0, err
	}
	instanceModel := resources.InstanceUses{Id: instanceUseId}
	err = instanceModel.GetByIdWithInstanceInfo(db)
	if err != nil {
		glog.Errorf("get instance failed:err %v", err)
		return 0, err
	}
	isOnline, err := GetInstanceAdbStatus(instanceModel.Instances.Machine.Ip + ":" + strconv.Itoa(instanceModel.Instances.AdbPort))
	if err != nil {
		glog.Errorf("get instance failed:err %v", err)
		return 0, err
	}
	if !isOnline {
		go AdbConnectWithTries(instanceModel.Instances.Machine.Ip+":"+strconv.Itoa(instanceModel.Instances.AdbPort), 3, instanceModel.Id)
	}
	State := instanceModel.State
	switch instanceModel.State {
	case int(resources.InstanceUseStatePending):
		if isOnline == true {
			State = 1
		}
	case int(resources.InstanceUseStateOnline):
		if isOnline == false {
			State = 2
		}
	case int(resources.InstanceUseStateOffline):
		if isOnline == true {
			State = 1
		}
	}
	err = ScreenshotForDevice(instanceModel.Instances.Machine.Ip+":"+strconv.Itoa(instanceModel.Instances.AdbPort), instanceUseId)
	if err != nil {
		glog.Errorf("screenshot for device failed:err %v", err)
	}
	instanceModel.State = State
	err = instanceModel.UpdatePartFields(db, map[string]interface{}{"state": State})
	if err != nil {
		glog.Errorf("update instance failed:err %v", err)
		return State, err
	}
	return State, nil
}

func CheckAllContainersState() error {
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get database connection failed, %s", err)
		return err
	}
	instanceModel := resources.InstanceUses{}
	instanceUses, err := instanceModel.GetUsingList(db)
	if err != nil {
		glog.Errorf("get instance failed:err %v", err)
		return err
	}
	for _, instanceUse := range instanceUses {
		if instanceUse.Instances.AdbInputInstalled == 0 {
			go func() {
				err := CheckAdbKeyInputInstalled(instanceUse.Id)
				if err != nil {
					glog.Errorf("check adb key input installed failed:err %v", err)
				}
			}()
		}
		if instanceUse.OperateTime.Add(time.Second * 10).After(time.Now()) {
			continue
		}
		go CheckContainerState(instanceUse.Id)
	}
	return nil
}
func CheckAdbKeyInputInstalled(instanceUseId int64) error {
	db, err := composite.Database.GetOrm()
	if err != nil {
		return err
	}
	instanceModel := resources.InstanceUses{Id: instanceUseId}
	err = instanceModel.GetByIdWithInstanceInfo(db)
	if err != nil {
		return err
	}
	udid := fmt.Sprintf("%s:%d", instanceModel.Instances.Machine.Ip, instanceModel.Instances.AdbPort)
	out, err := utils.RunA(exec.Command("adb", "-s", udid, "shell", "pm", "list", "packages"))
	if err != nil {
		return fmt.Errorf("list packages 失败: %v, 输出: %s", err, out)
	}
	adbIme := "com.android.adbkeyboard/.AdbIME"
	adbImePkg := "com.android.adbkeyboard"
	adbImeApkPath := "/root/ADBKeyboard.apk"
	if !strings.Contains(out, adbImePkg) {
		fmt.Println("ADB 输入法未安装，正在安装...")
		out2, err2 := runA(exec.Command("adb", "-s", udid, "install", "-r", adbImeApkPath))
		if err2 != nil {
			return fmt.Errorf("安装 ADB 输入法失败: %v, 输出: %s", err2, out2)
		}

	} else {
		// 3. 启用 ADB 输入法
		out, err = runA(exec.Command("adb", "-s", udid, "shell", "ime", "enable", adbIme))
		if err != nil {
			return fmt.Errorf("启用 ADB 输入法失败: %v, 输出: %s", err, out)
		}
		instanceModel.Instances.AdbInputInstalled = 1

		err = instanceModel.Instances.UpdatePartFields(db, map[string]interface{}{"adb_input_installed": 1})
		if err != nil {
			return err
		}
	}
	return nil
}
func GetInstanceAdbStatus(adbAddress string) (bool, error) {
	targetDevice := adbAddress

	// 获取设备列表
	devices, err := getADBDevices()
	if err != nil {
		fmt.Printf("获取设备列表失败: %v\n", err)
		return false, err
	}

	// 查找目标设备
	for _, dev := range devices {
		if strings.Contains(dev.Serial, targetDevice) {
			//found = true
			fmt.Printf("找到设备: %s\n", dev.Serial)
			fmt.Printf("状态: %s\n", dev.Status)

			// 进一步检查连接状态
			if isDeviceOnline(dev.Serial) {
				fmt.Println("设备已连接", dev.Serial)
				return true, nil
			} else {
				return false, nil
			}
		}
	}

	return false, nil
}

// DeviceInfo 表示ADB设备信息
type DeviceInfo struct {
	Serial string
	Status string
}

// getADBDevices 获取所有ADB设备列表
func getADBDevices() ([]DeviceInfo, error) {
	cmd := exec.Command("adb", "devices")
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		return nil, fmt.Errorf("执行adb命令出错: %v", err)
	}

	var devices []DeviceInfo
	lines := strings.Split(out.String(), "\n")

	// 跳过第一行标题行和最后一行空行
	for _, line := range lines[1 : len(lines)-1] {
		fields := strings.Fields(line)
		if len(fields) >= 2 {
			devices = append(devices, DeviceInfo{
				Serial: fields[0],
				Status: fields[1],
			})
		}
	}

	return devices, nil
}

// isDeviceOnline 检查设备是否真正在线
func isDeviceOnline(deviceID string) bool {
	cmd := exec.Command("adb", "-s", deviceID, "shell", "echo", "1")
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()

	// 如果能成功执行简单命令，说明设备在线
	return err == nil && strings.TrimSpace(out.String()) == "1"
}

func GetInstanceInfo(instanceUseId int64) (resources.InstanceUses, error) {
	instanceUse := resources.InstanceUses{Id: instanceUseId}
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get db failed:err %v", err)
		return instanceUse, err
	}
	err = instanceUse.GetByIdWithInstanceInfo(db)
	if err != nil {
		glog.Errorf("get instance use failed:err %v", err)
		return instanceUse, err
	}

	return instanceUse, nil
}
